package com.org.web.handle.user.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.org.platform.model.ResultModel;
import com.org.platform.utils.CommonUtil;
import com.org.web.handle.user.dao.UserMapper;
import com.org.web.handle.vo.UserVo;
import com.org.web.handle.wechat.service.WechatService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author devg @Date 2020/2/27 11:33
 */
@Slf4j
@Service
@Transactional
public class UserService extends ServiceImpl<UserMapper, UserVo> {

  @Autowired
  private WechatService wechatService;

  @Autowired
  private StringRedisTemplate stringRedisTemplate;

  @Autowired
  private UserMapper userMapper;

  @Autowired
  private HttpServletRequest request;

  @Autowired
  private HttpServletResponse response;

  public ResultModel checkLogin(UserVo userVo) {
    QueryWrapper<UserVo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("LOGIN_NAME", userVo.getLoginName());
    queryWrapper.eq("PASSWORD", userVo.getPassword());
    List<UserVo> userList = userMapper.selectList(queryWrapper);
    if (CommonUtil.isNullOrEmpty(userList)) {
      return ResultModel.newFail("用户或密码错误!");
    }
    /**
     * 登录成功 写入redis
     */
    UserVo user = userList.get(0);
    return writeToRedis(user);
  }

  public ResultModel writeToRedis(UserVo userVo) {
    if (null == userVo) {
      return ResultModel.newFail("user cannot be null");
    }
    String loginName = userVo.getLoginName();
    String loginUserKey = "loginUserKey:" + loginName;
    String tokenKey = stringRedisTemplate.opsForValue().get(loginUserKey);
    if (!CommonUtil.isNullOrEmpty(tokenKey)) {
      // 删除redis key
      stringRedisTemplate.delete(tokenKey);
    }
    String userInfo = JSON.toJSONString(userVo, SerializerFeature.WriteMapNullValue);
    String token = CommonUtil.getToken(loginName);
    stringRedisTemplate.opsForValue().set(token, userInfo, CommonUtil.maxAge, TimeUnit.DAYS);
    stringRedisTemplate.opsForValue().set(loginUserKey, token, CommonUtil.maxAge, TimeUnit.DAYS);
    CommonUtil.setCookieValue(response, CommonUtil.TOKEN, token, CommonUtil.maxAge * 24 * 60 * 60, true);
    Map<String, String> tokenMap = new HashMap<>();
    tokenMap.put("token", token);
    return ResultModel.newSuccess(tokenMap);
  }


  public ResultModel loginOut(String loginName) {
    if (CommonUtil.isNullOrEmpty(loginName)) {
      return ResultModel.newFail("登录用户不能为空");
    }
    String loginUserKey = "loginUserKey:" + loginName;
    String tokenKey = stringRedisTemplate.opsForValue().get(loginUserKey);
    if (!CommonUtil.isNullOrEmpty(tokenKey)) {
      stringRedisTemplate.delete(tokenKey);
    }
    stringRedisTemplate.delete(loginUserKey);
    return ResultModel.newSuccess();
  }

  public UserVo getUser() {
    // TODO Auto-generated method stub
    try {
//      String token = request.getHeader(CommonUtil.TOKEN);
      String token = CommonUtil.getCookieValue(request, CommonUtil.TOKEN);
      if (CommonUtil.isNullOrEmpty(token)) {
        token = request.getHeader(CommonUtil.TOKEN);
      }
      if (CommonUtil.isNullOrEmpty(token)) {
        return null;
      }
      String userInfo = stringRedisTemplate.opsForValue().get(token);
      UserVo User = null;
      if (!CommonUtil.isNullOrEmpty(userInfo)) {
        User = JSON.parseObject(userInfo, UserVo.class);
      }
      if (null != User) {
        return User;
      }
    } catch (Exception ex) {
      log.error(ex.getMessage());
    }
    return null;
  }

  public ResultModel wechatLogin(String code, String state) {
    if (CommonUtil.isNullOrEmpty(code)) {
      String errMsg = "wechat login fail,code cannot be null";
      log.error(errMsg);
      return ResultModel.newFail(errMsg);
    }
    // 第一步： 判断User是否为空
    UserVo userVo = getUser();
    if (null != userVo) {
      String errMsg = "User logged in";
      log.error(errMsg);
      return ResultModel.newFail(errMsg);
    }
    // 第二步: 通过code获取accessToken
    JSONObject accessTokenObjct = wechatService.getAccessToken(code);
    String accessToken = accessTokenObjct.getString("access_token");
    String openId = accessTokenObjct.getString("openid");
    if (CommonUtil.isNullOrEmpty(accessToken) || CommonUtil.isNullOrEmpty(openId)) {
      String errMsg = "accessToken and openid cannot be null";
      log.error(errMsg);
      return ResultModel.newFail(errMsg);
    }
    log.info("accessToken:{},openId:{}", accessToken, openId);
    // 第三步： 通过accessToken和openId获取用户信息
    JSONObject wechatUserInfo = wechatService.getUserInfo(accessToken, openId);
    log.info("userInfo:{}", JSON.toJSONString(wechatUserInfo));
    String wechatOpenId = wechatUserInfo.getString("openid");
    String wechatUserName = wechatUserInfo.getString("nickname");
    String headImgurl = wechatUserInfo.getString("headimgurl");
    // 第四步： 写入redis
    UserVo wechatUserVo = new UserVo();
    wechatUserVo.setOpenId(wechatOpenId);
    wechatUserVo.setLoginName(wechatOpenId);
    wechatUserVo.setUserName(wechatUserName);
    wechatUserVo.setHeadImgurl(headImgurl);
    return writeToRedis(wechatUserVo);
  }
}
